package spider.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import spider.dao.TbConfigDao;
import spider.entity.TbConfig;
import spider.utils.HttpUtils;
import spider.utils.JsonPathUtil;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;

/**
 * @author Administrator
 */
@Slf4j
@Service
public class SpiderData {
    @Autowired
    TbConfigDao tbConfigDao;
    @Value(value = "${max.page}")
    private int maxPage;
    @Value(value = "${thread.wait.time}")
    private Long waitTime;
    @Autowired
    HttpUtils httpUtils;

    private final Object objectLock = new Object();

    public void start() {
//        TbConfig item = tbConfigDao.selectByPrimaryKey("716672a8-091d-11eb-9f2b-029b50ac1fc5");
//        if ("get".equals(item.getMethod())) {
//            getMethod(item);
//        } else {
//            postMethod(item);
//        }
        List<TbConfig> list = tbConfigDao.listConfig();
        if (list.size() > 0) {
            list.forEach(item -> {
                if ("get".equals(item.getMethod())) {
                    getMethod(item);
                } else {
                    postMethod(item);
                }
            });
        }
    }

    private void getMethod(TbConfig tbConfig) {
        for (int i = tbConfig.getStartIndex(); i < maxPage; i++) {
            String url = tbConfig.getUrl().replace("[pageNo]", String.valueOf(i));
            log.info(tbConfig.getName() + "  网站正在爬取第： " + i + "  页");
            String resp = httpUtils.httpGet(tbConfig, url);
            if (!analysisData(tbConfig, resp)) {
                break;
            } else {
                lockThread();
            }
        }
    }

    private boolean analysisData(TbConfig tbConfig, String resp) {
        if (resp != null) {
            List<Map<String, Object>> list = JsonPathUtil.analysisJsonData(resp, tbConfig.getJsonPath(), List.class);
            if (list == null || list.size() == 0) {
                log.info("analysisData方法:" + tbConfig.getName() + ",list的值为：" + list);
                return false;
            }
            JSONObject jsonObject = JSONObject.parseObject(tbConfig.getJsonFieldMapping());
            JSONObject remarkObject = JSONObject.parseObject(tbConfig.getRemarks());
            Map<String, Object> map = new HashMap<>(16);
            list.forEach(item -> {
                jsonObject.keySet().forEach(key -> {
                    if (remarkObject != null && "pic".equals(key) && remarkObject.get("picPre") != null) {
                        map.put(key, remarkObject.getString("picPre") + item.get(jsonObject.getString(key)));
                    } else {
                        if (jsonObject.getString(key).contains(".")) {
                            map.put(key, getItemData(item, jsonObject.getString(key)));
                        } else {
                            map.put(key, item.get(jsonObject.getString(key)));
                        }
                    }
                });
                map.put("appName", tbConfig.getName());
                //如果换成批量的，将这段代码放在list循环之外即可，同时将map改为list
                sendBusiness(map);
            });
        }
        return true;
    }

    private String getItemData(Map<String, Object> item, String jsonPath) {
        try {
            String itemData = JSON.toJSONString(item);
            return JsonPathUtil.analysisJsonData(itemData, jsonPath, String.class);
        } catch (Exception e) {
            return null;
        }
    }

    private void lockThread() {
        synchronized (objectLock) {
            try {
                objectLock.wait(waitTime);
            } catch (InterruptedException e) {
                log.error(FINALIZE_SESSION_MARKER, "", e);
                Thread.currentThread().interrupt();
            }
        }
    }

    private void sendBusiness(Map<String, Object> map) {

    }

    private void postMethod(TbConfig tbConfig) {
        for (int i = tbConfig.getStartIndex(); i < maxPage; i++) {
            String jsonBody = tbConfig.getDataBody().replace("[pageNo]", String.valueOf(i));
            if (tbConfig.getName().contains("")) {
                JSONObject remarkObject = JSONObject.parseObject(tbConfig.getRemarks());
                if (remarkObject != null && remarkObject.get("step") != null) {
                    jsonBody = tbConfig.getDataBody().replace("[offset]", String.valueOf(i * remarkObject.getInteger("step")));
                }
            }
            JSONObject jsonObject = JSONObject.parseObject(jsonBody);
            if (tbConfig.getName().contains("美家")) {
                jsonObject.put("page", i);
            }
            String resp = null;
            if ("data".equals(tbConfig.getPostType())) {
                resp = httpUtils.httpSendForm(tbConfig, jsonObject);
            } else {
                resp = httpUtils.httpPostJson(tbConfig, jsonObject);
            }
            if (!analysisData(tbConfig, resp)) {
                break;
            } else {
                lockThread();
            }
        }
    }


}
